package com.myt.matp.gui;

import com.myt.matp.core.EventListener;
import com.myt.matp.core.Event;
import com.myt.matp.MATlet;
import com.myt.matp.utils.Color;
import com.myt.matp.utils.Edit;
import com.myt.matp.utils.KeyCodeAdapter;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public final class GUI extends Canvas implements EventListener {

    public static final int MAX_SIZE = 0x0FFFFFFF;
    public static final int MIN_SIZE = 0;

    public static final int KEY_NONE = 0;
    public static final int KEY_UP = 1;
    public static final int KEY_DOWN = 2;
    public static final int KEY_LEFT = 3;
    public static final int KEY_RIGHT = 4;
    public static final int KEY_OK = 5;
    public static final int KEY_SOFTLEFT = 6;
    public static final int KEY_SOFTRIGHT = 7;
    public static final int KEY_CLEAR = 8;
    public static final int KEY_POUND = 35; // #
    public static final int KEY_STAR = 42;  // *
    public static final int KEY_0 = 48;
    public static final int KEY_1 = 49;
    public static final int KEY_2 = 50;
    public static final int KEY_3 = 51;
    public static final int KEY_4 = 52;
    public static final int KEY_5 = 53;
    public static final int KEY_6 = 54;
    public static final int KEY_7 = 55;
    public static final int KEY_8 = 56;
    public static final int KEY_9 = 57;

    private MATlet m_MATlet = null;
    private MGraphics m_Graphics = null;
    private UIWidget m_UI = null;
    private UIWidget m_PopUp = null;

    private Color m_Color = new Color();

    private KeyCodeAdapter m_KeyCodeAdapter;

    public GUI(MATlet m) {
	m_MATlet = m;
        setFullScreenMode(true);
	m_Graphics = createMGraphics();
	m_KeyCodeAdapter = new KeyCodeAdapter(this);
    }

    /*
     * UI
     *
     */

    public void setUI(UIWidget ui) {
	if (m_UI != null) {
	    m_UI.unsetFocus();
	    m_UI.setRepaint(false);
	}
	m_UI = ui;
	if (m_UI != null) {
	    m_UI.setFocus();
	    m_UI.setRepaint(true);
	}
	resizeUI();
	repaintUI();
	//postEvent(Event.UI_SHOW, 0, 0, null);
    }

    public UIWidget getUI() {
	return m_UI;
    }

    public void setPopUp(UIWidget popUp) {
	if (m_PopUp != null) {
	    m_PopUp.unsetFocus();
	    m_PopUp.setRepaint(false);	    
	}
	m_PopUp = popUp;
	if (m_PopUp != null) {
	    m_PopUp.setFocus();
	    m_PopUp.setRepaint(true);
	    m_PopUp.redraw();
	}	
	postEvent(Event.UI_REPAINT, 0, 0, null);
    }

    public UIWidget getPopUp() {
	return m_PopUp;
    }

    private void resizeUI() {
	if (m_UI != null) {
	    m_UI.setPosX(0);
	    m_UI.setPosY(0);
	    m_UI.resize(getWidth(), getHeight());
	}
    }

    private void repaintUI() {
	repaint();
    }

    /*
     * Color
     *
     */

    public int getColorFocus(int rgb, boolean focus) {
	int ret = rgb;

	m_Color.setRGB(rgb);
	if (focus) {
	    ret = rgb;
	} else {
	    m_Color.adjustSaturation(15f);	    
	    ret = m_Color.getRGB();
	}

	return ret;
    }

    /*
     * Fonts
     *
     */

    public void setFont(int face, int style, int size) {
	m_MATlet.getFontSystem().setFont(face, style, size);
    }

    public int getFontHeight() {
	return m_MATlet.getFontSystem().getFontHeight();
    }

    public int getCharWidth(char c) {
	return m_MATlet.getFontSystem().charWidth(c);
    }

    public int getCharsWidth(Edit editor, int start, int length) {
	return m_MATlet.getFontSystem().charsWidth(editor, start, length);
    }

    /*
     * Painting
     *
     */

    protected void paint(final Graphics g) {
        //#ifdef DEBUG_GUI
        //# System.out.println(getClass().getName() + ".paint(Graphics g) {");
        //#endif
	// Save current context device
	m_Graphics.setGraphics(g);
	// Paint controls in first plane
	if (m_UI != null) {
	    //#ifdef DEBUG_GUI
	    //# System.out.println("\tpainting UI");
	    //#endif
	    m_UI.paint(m_Graphics);
	}
	// Paint Controls en second plane
	if (m_PopUp != null) {
	    //#ifdef DEBUG_GUI
	    //# System.out.println("\tpainting popup");
	    //#endif
	    m_PopUp.paint(m_Graphics);
	}
        //#ifdef DEBUG_GUI
        //# System.out.println("}");
        //#endif
    }

    /*
     *
     * Alarms
     *
     */
    protected void initAlarm(int id, long period, EventListener e) {
	m_MATlet.initAlarm(id, period, e);
    }

    protected void killAlarm(int id) {
	m_MATlet.killAlarm(id);
    }

    /*
     *
     * events
     *
     */

    protected void postEvent(int id, int iParam, long lParam, Object oParam) {
	m_MATlet.postEvent(id, iParam, lParam, oParam);
    }

    public boolean dispatchEvent(final Event e) {
	boolean ret = true;
	if (!dispatchEventGUI(e)) {
	    if (!dispatchEventPopUp(e)) {
		ret = dispatchEventUI(e);
	    }
	}
	return ret;
    }

    private boolean dispatchEventGUI(final Event e) {
	boolean ret = true;
	switch (e.getId()) {
	case Event.UI_RESIZE:
	    resizeUI();
	    postEvent(Event.UI_REPAINT, 0, 0, null);
	    break;
	case Event.UI_REPAINT:
	    repaintUI();
	    break;
	case Event.UI_SHOW:
	    postEvent(Event.UI_RESIZE, 0, 0, null);
	    break;
	default:
	    ret = false;
	    break;
	}
	return ret;
    }

    private boolean dispatchEventPopUp(final Event e) {
	boolean ret = false;
	if (m_PopUp != null) {
	    ret = m_PopUp.dispatchEvent(e);
	}
	return ret;
    }

    private boolean dispatchEventUI(final Event e) {
	boolean ret = false;
	if (m_UI != null) {
	    ret = m_UI.dispatchEvent(e);
	}
	return ret;
    }

    /*
     * Keys
     *
     */

    protected void keyPressed(int keyCode) {
	postEvent(Event.UI_KEY_PRESSED, translateKey(keyCode), 0, null);
    }

    protected void keyReleased(int keyCode) {
	postEvent(Event.UI_KEY_RELEASED, translateKey(keyCode), 0, null);
    }


    /*
     * Widgets
     *
     */

    public UIWidget createWidget(int type, int id) {
	UIWidget w = null;
	switch (type) {
	case UIWidget.PANEL:
	    w = new UIPanel(id, this);
	    break;
	case UIWidget.EDIT:
	    w = new UIEdit(id, this);
	    break;
	case UIWidget.SOFT:
	    w = new UISoft(id, this);
	    break;
	case UIWidget.MENU:
	    w = new UIMenu(id, this);
	    break;
	case UIWidget.BUTTON:
	    w = new UIButton(id, this);
	    break;
	case UIWidget.IMAGE:
	    w = new UIImage(id, this);
	    break;
	case UIWidget.SCROLLBAR:
	    w = new UIScrollBar(id, this);
	    break;
	case UIWidget.ITEM:
	    w = new UIItem(id, this);
	    break;
	}
	return w;
    }

    public UIPanel createUIPanel(int id) {
	return (UIPanel)createWidget(UIWidget.PANEL, id);
    }

    public UIEdit createUIEdit(int id) {
	return (UIEdit)createWidget(UIWidget.EDIT, id);
    }

    public UISoft createUISoft(int id) {
	return (UISoft)createWidget(UIWidget.SOFT, id);
    }

    public UIMenu createUIMenu(int id) {
	return (UIMenu)createWidget(UIWidget.MENU, id);
    }

    public UIButton createUIButton(int id) {
	return (UIButton)createWidget(UIWidget.BUTTON, id);
    }

    public UIImage createUIImage(int id) {
	return (UIImage)createWidget(UIWidget.IMAGE, id);
    }

    public UIScrollBar createUIScrollBar(int id) {
	return (UIScrollBar)createWidget(UIWidget.SCROLLBAR, id);
    }

    public UIItem createUIItem(int id) {
	return (UIItem)createWidget(UIWidget.ITEM, id);
    }

    /*
     * Paint functions
     *
     */

    public MGraphics createMGraphics() {
	MGraphics g = new MGraphics(m_MATlet.getFontSystem());
	return g;
    }

    /*
     * Key Codes
     *
     */

    protected final int translateKey(int code) {
	code = m_KeyCodeAdapter.adoptKeyCode(code);
        switch(code) {
	case KeyCodeAdapter.KEY_0:
	    code = GUI.KEY_NUM0;
	    break;
	case KeyCodeAdapter.KEY_1:
	    code = GUI.KEY_NUM1;
	    break;
	case KeyCodeAdapter.KEY_2:
	    code = GUI.KEY_NUM2;
	    break;
	case KeyCodeAdapter.KEY_3:
	    code = GUI.KEY_NUM3;
	    break;
	case KeyCodeAdapter.KEY_4:
	    code = GUI.KEY_NUM4;
	    break;
	case KeyCodeAdapter.KEY_5:
	    code = GUI.KEY_NUM5;
	    break;
	case KeyCodeAdapter.KEY_6:
	    code = GUI.KEY_NUM6;
	    break;
	case KeyCodeAdapter.KEY_7:
	    code = GUI.KEY_NUM7;
	    break;
	case KeyCodeAdapter.KEY_8:
	    code = GUI.KEY_NUM8;
	    break;
	case KeyCodeAdapter.KEY_9:
	    code = GUI.KEY_NUM9;
	    break;
	case KeyCodeAdapter.KEY_POUND:
	    code = GUI.KEY_POUND;
	    break;
	case KeyCodeAdapter.KEY_STAR:
	    code = GUI.KEY_STAR;
	    break;
	case KeyCodeAdapter.KEY_UP:
	    code = GUI.KEY_UP;
	    break;
	case KeyCodeAdapter.KEY_DOWN:
	    code = GUI.KEY_DOWN;
	    break;
	case KeyCodeAdapter.KEY_LEFT:
	    code = GUI.KEY_LEFT;
	    break;
	case KeyCodeAdapter.KEY_RIGHT:
	    code = GUI.KEY_RIGHT;
	    break;
	case KeyCodeAdapter.KEY_SOFT_MIDDLE_INTERNET:
	case KeyCodeAdapter.KEY_CENTER:
	    code = GUI.KEY_OK;
	    break;
	case KeyCodeAdapter.KEY_SOFT_LEFT:
	    code = GUI.KEY_SOFTLEFT;
	    break;
	case KeyCodeAdapter.KEY_SOFT_RIGHT:
	    code = GUI.KEY_SOFTRIGHT;
	    break;
	case KeyCodeAdapter.KEY_BACK:
	    code = GUI.KEY_CLEAR;
	    break;
	default:
	    code = GUI.KEY_NONE;
	}

        return code;
    }

}